package labox.innovation.gameserver.model;

import java.util.HashMap;
import java.util.Map;
import labox.innovation.gameserver.model.actor.L2Npc;
import labox.innovation.gameserver.model.actor.instance.FuzeNpcInstance;
import labox.innovation.gameserver.model.actor.instance.FuzePcInstance;
import labox.innovation.gameserver.model.actor.instance.FuzeWaypointInstance;
import labox.innovation.gameserver.model.listener.INpcFaceStateListenr;
import labox.innovation.gameserver.model.listener.LocationListener;
import labox.innovation.gameserver.network.serverpackets.RadarControl;

/**
 * 
 * 玩家的客户端对象的雷达类，处理客户端右上角的小地图上的各类显示
 * 
 * @author Administrator
 * 
 */
public final class L2Radar implements INpcFaceStateListenr, LocationListener {

	/**
	 * 代表一般的npc
	 */
	public static final int GEN_NPC = 0x00;

	/**
	 * 代表可接任务npc枚举
	 */
	public static final int ACCEPTNPC = 0x01;

	/**
	 * 代表未完成任务NPC枚举
	 */
	public static final int UNSUCCESS = 0x02;

	/**
	 * 代表可交还任务npc枚举
	 */
	public static final int RETURNNPC = 0x03;

	/**
	 * 增加操作
	 */
	public static final int SHOWRADAR_ADD = 0x00;

	/**
	 * 更新
	 */
	public static final int SHOWRADAR_UPDATE = 0x01;

	/**
	 * 删除
	 */
	public static final int SHOWRADAR_DELETE = 0x02;

	public static final int MARKERTYPE_POINT = 0x00;

	public static final int MARKERTYPE_FLASH = 0x01;

	private FuzePcInstance _player;

	private Map<Long, RadarMarker> _markers;

	private boolean _disable;

	public L2Radar(FuzePcInstance owner) {
		_player = owner;
		_markers = new HashMap<Long, RadarMarker>();
	}

	public void setOwner(FuzePcInstance owner) {
		_player = owner;
	}

	public void setDisable(boolean disable) {
		boolean old = _disable;
		if (old && !disable) {
			for (RadarMarker marker : _markers.values()) {
				_player.sendPacket(new RadarControl(marker._objId, SHOWRADAR_ADD, marker._color, marker._type, marker._x, marker._y));
			}
		}
		_disable = disable;
	}

	// Add a marker to player's radar when partymember
	private final void addMarker(long objId, int x, int y, int type, int color) {
		RadarMarker newMarker = new RadarMarker(objId, color, type, x, y);
		_markers.put(objId, newMarker);
		if (!_disable)
			_player.sendPacket(new RadarControl(objId, SHOWRADAR_ADD, color, type, x, y));
	}

	/**
	 * 增加小地图上的标记
	 * 
	 * @param obj
	 * 
	 */
	public final void addMarker(L2Object obj) {
		if (obj == _player)
			return;
		if (obj instanceof FuzeNpcInstance) {
			int questInfo = _player.getNpcQuestFace((L2Npc) obj);
			switch (questInfo) {
			case ACCEPTNPC:
				addMarker(obj.getObjectId(), obj.getX(), obj.getY(), MARKERTYPE_POINT, 0xffff00);
				break;
			case RETURNNPC:
				addMarker(obj.getObjectId(), obj.getX(), obj.getY(), MARKERTYPE_FLASH, 0xffff00);
				break;
			}
		} else if (obj instanceof FuzeWaypointInstance) {//跳转点
			addMarker(obj.getObjectId(), obj.getX(), obj.getY(), MARKERTYPE_POINT, 0xff0000);
		} else if (obj instanceof FuzePcInstance) {//玩家
			FuzePcInstance p = ((FuzePcInstance) obj);
			//判断是不是队员，不是队员不监听
			if (!_player.isInParty() || _player.getParty() != p.getParty() || obj.getScene() != _player.getScene() || obj.getInstanceId() != _player.getInstanceId())
				return;
			//监听对方的坐标变化
			p.getPosition().addLocationListener(this);
			//让对方监听自己的坐标变化
			_player.getPosition().addLocationListener(p.getRadar());
			//把对方加入雷达标记
			addMarker(obj.getObjectId(), obj.getX(), obj.getY(), MARKERTYPE_POINT, 0x0000ff);
			//加入对方雷达标记
			p.getRadar().addMarker(_player.getObjectId(), _player.getX(), _player.getY(), MARKERTYPE_POINT, 0x0000ff);
		}
	}

	public final void removeMarker(L2Object obj) {
		RadarMarker mark = _markers.remove(obj.getObjectId());
		if (mark == null)
			return;
		if (obj instanceof FuzePcInstance) {
			((FuzePcInstance) obj).getPosition().removeLocationListener(this);
		}
		if (!_disable)
			_player.sendPacket(new RadarControl(mark._objId, SHOWRADAR_DELETE, mark._color, mark._type, mark._x, mark._y));
	}

	public final void removeAllMarkers() {
		// 清除时，要在当前场景上其他玩家的雷达上注销自己
		for (RadarMarker mark : _markers.values()) {
			FuzePcInstance member = FuzeWorld.getInstance().getPlayer(mark._objId);
			if (member == null)
				continue;
			member.getRadar().removeMarker(_player);
		}
		_markers.clear();
	}

	/**
	 * 坐标变化监听器回调
	 * 
	 * @param objectId
	 * @param x
	 * @param y
	 */
	@Override
	public void Location(long objectId, int x, int y) {
		RadarMarker mark = _markers.get(objectId);
		if (mark == null)
			return;
		mark.setXY(x, y);
		if (!_disable)
			_player.sendPacket(new RadarControl(mark._objId, SHOWRADAR_UPDATE, mark._color, mark._type, mark._x, mark._y));
	}

	/**
	 * 实现NPC小地图表情状态监听接口
	 */
	public void notifyNpcStateChanged(L2Object obj) {
		if (obj == _player)
			return;
		if (obj instanceof FuzeNpcInstance) {

			FuzeNpcInstance npc = (FuzeNpcInstance) obj;
			if (npc.getScene() != _player.getScene())
				return;

			int questInfo = _player.getNpcQuestFace(npc);

			RadarMarker mark = _markers.get(obj.getObjectId());
			switch (questInfo) {
			case ACCEPTNPC:
				if (mark == null) {
					addMarker(obj.getObjectId(), obj.getX(), obj.getY(), MARKERTYPE_POINT, 0xffff00);
				} else {
					mark._type = MARKERTYPE_POINT;
					mark._color = 0xffff00;
					if (!_disable)
						_player.sendPacket(new RadarControl(mark._objId, SHOWRADAR_UPDATE, 0xffff00, MARKERTYPE_POINT, mark._x, mark._y));
				}
				break;
			case RETURNNPC:
				if (mark == null) {
					addMarker(obj.getObjectId(), obj.getX(), obj.getY(), MARKERTYPE_FLASH, 0xffff00);
				} else {
					mark._type = MARKERTYPE_FLASH;
					mark._color = 0xffff00;
					if (!_disable)
						_player.sendPacket(new RadarControl(mark._objId, SHOWRADAR_UPDATE, 0xffff00, MARKERTYPE_FLASH, mark._x, mark._y));
				}
				break;
			default:
				//如果不是上面两个状态的NPC，删除他
				if (mark != null) {
					removeMarker(obj);
				}
				break;
			}
		}
	}

	/**
	 * 雷达上的点的对象
	 * 
	 * @author Administrator
	 * 
	 */
	public class RadarMarker {
		// Simple class to model radar points.
		public int _type;

		public int _color;

		public int _x, _y;

		public long _objId;

		public RadarMarker(long objId, int color, int type, int x, int y) {
			_objId = objId;
			_color = color;
			_type = type;
			_x = x;
			_y = y;

		}

		public void setX(int x) {
			_x = x;
		}

		public void setY(int y) {
			_y = y;
		}

		public void setXY(int x, int y) {
			_x = x;
			_y = y;
		}
	}
}
